/*
 * Copyright (c) 2009, Jan Pastor. All Rights Reserved.
 */

package sk.jp.jitag.model.config;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.db4o.config.annotations.Indexed;

import sk.jp.commons.exception.ApplicationException;
import sk.jp.commons.exception.IllegalInputException;
import sk.jp.commons.utils.ExceptionUtils;
import sk.jp.jitag.dao.db4o.BaseEntity;
import sk.jp.jitag.dao.db4o.Unique;
import sk.jp.jitag.dao.db4o.CascadeOnDelete;
import sk.jp.jitag.util.Msg;

/**
 * Application configuration.
 */
public class Config extends BaseEntity {

    /**
     * {profile Id -> profile}
     */
    @CascadeOnDelete
    private List<Profile> profiles;

    @Indexed
    @Unique
    private String currentProfileId;

    /**
     * This enforce singleton instance in database.
     */
    @Indexed
    @Unique
    private String configId = "jitagConfig";

    //----------------------------------------------------------------------

    public Config() {
        profiles = createList(0);
        Profile defaultProfile = createEmptyProfile("Default", Msg.configProfileDefault.value());
        profiles.add(defaultProfile);
        currentProfileId = defaultProfile.getId();
    }

    //----------------------------------------------------------------------

    public synchronized Profile getCurrentProfile() {
        return getProfiles().get(currentProfileId);
    }

    public synchronized void setCurrentProfileId(String currentProfileId) {
        this.currentProfileId = currentProfileId;
    }

    /**
     * Returns a map of profiles.
     * @return a map. where key is profile ID ({@link Profile#getId()}.
     */
    public synchronized Map<String, Profile> getProfiles() {
        Map<String, Profile> profilesMap = new HashMap<String, Profile>();
        for (Profile profile : profiles) {
            profilesMap.put(profile.getId(), profile);
        }
        return profilesMap;
    }

    public synchronized void addProfile(Profile profile){
        if(!profiles.contains(profile)){
            profiles.add(profile);
        }
    }

    public synchronized void removeProfile(Profile profile) {
        profiles.remove(profile);
    }

    public synchronized Profile createEmptyProfile(String label, String description){
        Profile profile = new Profile(label);
        profile.setDescription(description);
        return profile;
    }

    public synchronized Profile createCopyOfProfile(String sourceProfileId, String label,
                                                    String description){
        Profile srcProfile = getProfiles().get(sourceProfileId);
        if(srcProfile == null){
            throw new ApplicationException("Configuration profile not found",
                                           null,//TODO Dokoncit!!! code
                                           ExceptionUtils.paramsToMap("sourceProfileId",
                                                                      sourceProfileId));
        }
        if(srcProfile.getLabel().equals(label)){
            throw new IllegalInputException("Label of new profile can not equals to source profile label",
                                            null,  //TODO Dokoncit!!! code
                                            ExceptionUtils.paramsToMap("label", label));
        }

        Profile profile = srcProfile.clone();//TODO Dokoncit!!! Toto asi spravit inak, nie cez clone?!
        profile.setLabel(label);
        profile.setLabel(description);
        return profile;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("Config");
        sb.append("{profiles=").append(profiles);
        sb.append(", currentProfileId='").append(currentProfileId).append('\'');
        sb.append('}');
        return sb.toString();
    }
}
